package com.gitee.feizns.quickstart.dict;

import com.github.benmanes.caffeine.cache.Cache;
import com.github.benmanes.caffeine.cache.Caffeine;

import java.util.ArrayList;
import java.util.List;

/**
 * caffeine dict 储藏器
 * @author feizns
 * @since 2025/1/6
 */
public class CaffeineDictDepositor<T extends Entry> extends AbstractDictDepositor<T> {

    /**
     * 缓存
     */
    private final Cache<String, T> cache;

    /**
     * 咖啡因 dict 储藏器
     */
    public CaffeineDictDepositor() {
        this.cache = Caffeine.newBuilder().build();
    }

    /**
     * 咖啡因 dict 储藏器
     * @param cache 缓存
     */
    public CaffeineDictDepositor(Cache<String, T> cache) {
        this.cache = cache;
    }

    /**
     * 咖啡因 dict 储藏器
     * @param cache 缓存
     * @param depositor 存户
     */
    public CaffeineDictDepositor(Cache<String, T> cache, DictDepositor<T> depositor) {
        super(depositor);
        this.cache = cache;
    }

    @Override
    public DictDepositor<T> reload() {
        if ( delegate != null ) {
            delegate.reload();
            delegate.list().forEach(e -> cache.put(e.getKey(), e));
        }
        return this;
    }

    @Override
    public List<T> list() {
        return new ArrayList<>(cache.asMap().values());
    }

    @Override
    public T get(String key) {
        return cache.get(key, delegate::get);
    }

    @Override
    public void put(T entry) {
        T dict = get(entry.getKey());
        if ( dict != null && dict.getPermission() == Permission.ReadOnly )
            throw new UnsupportedOperationException(String.format("不支持修改只读字典[%s]", dict.getKey()));
        cache.put(entry.getKey(), entry);
        //代理存储
        delegate.put(entry);
    }

    @Override
    public boolean exists(String key) {
        return get(key) != null;
    }

    @Override
    public T delete(String key) {
        T entry = get(key);
        if ( entry != null ) {
            if ( entry.getPermission() == Permission.ReadOnly )
                throw new UnsupportedOperationException(String.format("不支持删除只读字典[%s]", entry.getKey()));
            cache.invalidate(key);
            delegate.delete(key);
        }
        return entry;
    }

}
